package com.eric.utils;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;
import org.jsoup.nodes.Element;

import com.linkedin.urls.Url;
import com.linkedin.urls.detection.UrlDetector;
import com.linkedin.urls.detection.UrlDetectorOptions;

/**
 * url及html处理工具类。<br>
 * 
 * @author code4crafter@gmail.com <br>
 *         Date: 13-4-21 Time: 下午1:52
 */
public class UrlUtils {

	private static Pattern relativePathPattern = Pattern.compile("^([\\.]+)/");

	/**
	 * 将url想对地址转化为绝对地址
	 * 
	 * @param url
	 *            url地址
	 * @param refer
	 *            url地址来自哪个页面
	 * @return url绝对地址
	 */
	public static String canonicalizeUrl(String url, String refer) {
		if (StringUtils.isBlank(url) || StringUtils.isBlank(refer)) {
			return url;
		}
		if (url.startsWith("http") || url.startsWith("ftp") || url.startsWith("mailto")
				|| url.startsWith("javascript:")) {
			return url;
		}
		if (StringUtils.startsWith(url, "/")) {
			String host = getHost(refer);
			return host + url;
		} else if (!StringUtils.startsWith(url, ".")) {
			refer = reversePath(refer, 1);
			return refer + "/" + url;
		} else {
			Matcher matcher = relativePathPattern.matcher(url);
			if (matcher.find()) {
				int reverseDepth = matcher.group(1).length();
				refer = reversePath(refer, reverseDepth);
				String substring = StringUtils.substring(url, matcher.end());
				return refer + "/" + substring;
			} else {
				refer = reversePath(refer, 1);
				return refer + "/" + url;
			}
		}
	}

	public static boolean isUrl(String input) {
		UrlDetector parser = new UrlDetector(input, UrlDetectorOptions.Default);
		List<Url> found = parser.detect();
		if (found.size() > 0)
			return true;
		else
			return false;
	}

	public static String handleUrl(String url) {
		UrlDetector parser = new UrlDetector(url, UrlDetectorOptions.Default);
		List<Url> found = parser.detect();
		if (found.size() > 0) {
			return found.get(0).toString();
		} else {
			return url;
		}

	}

	public static String reversePath(String url, int depth) {
		int i = StringUtils.lastOrdinalIndexOf(url, "/", depth);
		if (i < 10) {
			url = getHost(url);
		} else {
			url = StringUtils.substring(url, 0, i);
		}
		return url;
	}

	public static String getHost(String url) {
		String host = url;
		int i = StringUtils.ordinalIndexOf(url, "/", 3);
		if (i > 0) {
			host = StringUtils.substring(url, 0, i);
		}
		return host;
	}

	private static Pattern patternForProtocal = Pattern.compile("[\\w]+://");

	public static String removeProtocol(String url) {
		return patternForProtocal.matcher(url).replaceAll("");
	}

	public static String getDomain(String url) {
		String domain = removeProtocol(url);
		int i = StringUtils.indexOf(domain, "/", 1);
		if (i > 0) {
			domain = StringUtils.substring(domain, 0, i);
		}
		return domain;
	}

	private static Pattern patternForHref = Pattern.compile("(<a[^<>]*href=)[\"']{0,1}([^\"'<>\\s]*)[\"']{0,1}",
			Pattern.CASE_INSENSITIVE);

	public static String fixAllRelativeHrefs(String html, String url) {
		StringBuilder stringBuilder = new StringBuilder();
		Matcher matcher = patternForHref.matcher(html);
		int lastEnd = 0;
		while (matcher.find()) {
			stringBuilder.append(StringUtils.substring(html, lastEnd, matcher.start()));
			stringBuilder.append(matcher.group(1));
			stringBuilder.append("\"").append(canonicalizeUrl(matcher.group(2), url)).append("\"");
			lastEnd = matcher.end();
		}
		stringBuilder.append(StringUtils.substring(html, lastEnd));
		return stringBuilder.toString();
	}

	private static final Pattern patternForCharset = Pattern.compile("charset=([^\\s;]*)");

	public static String getCharset(String contentType) {
		Matcher matcher = patternForCharset.matcher(contentType);
		if (matcher.find()) {
			return matcher.group(1);
		} else {
			return null;
		}
	}

	public static String properLink(String strUrl) {
		URL url = null;
		try {
			url = new URL(strUrl);
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
		if (strUrl.startsWith("http")) {
			return strUrl;
		} else {
			return strUrl.replaceAll("^", "http://" + url.getHost());
		}
	}

	/**
	 * 检查url1和url2是否具有同样的root domain 如果否，则返回true，即是external链接
	 * 
	 * @param url1
	 * @param url2
	 * @return
	 */
	public static boolean isExternal(String url1, String url2) {
		GetRoot gr = new GetRoot();
		String root1 = null;
		String root2 = null;
		root1 = gr.getRoot(url1);
		root2 = gr.getRoot(url2);

		if (root1.equals(root2))
			return false;
		else
			return true;
	}

	public boolean isAbsolute(Element a) {
		String url = a.attr("href");
		try {
			if (url.startsWith("http") && (new URL(url) != null))
				return true;
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
		return false;
	}

	public boolean isDynamic(Element a) {
		String url = a.attr("href");
		if (url.contains("?"))
			return true;
		return false;
	}

	public static String robotsUrl(String url) {
		URL URL = null, robotsUrl = null;
		try {
			URL = new URL(url);

		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
		try {
			robotsUrl = new URL(URL.getProtocol() + "://" + URL.getHost() + "/robots.txt");
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
		return robotsUrl.toString();
	}

	public static String getRoot(String url) {
		URL URL = null;
		try {
			URL = new URL(url);
		} catch (MalformedURLException e1) {
			e1.printStackTrace();
		}
		return getRoot(URL);

	}

	public static String getRoot(URL url) {
		StringBuffer root = new StringBuffer();

		String host = url.getHost();

		String[] rootMembers = host.split("\\.");

		int n = 2;

		if (rootMembers.length > 2) {
			String secondLastMember = rootMembers[rootMembers.length - 2];

			if (secondLastMember.matches("^com$|^net$|^gov$|^edu$|^co$|^org$"))
				n = 3;
		}

		for (int i = n; i > 0; i--) {
			try {
				root.append(rootMembers[host.split("\\.").length - i]);
				if ((i - 1) > 0)
					root.append(".");
			} catch (java.lang.ArrayIndexOutOfBoundsException e) {

			}
		}

		return root.toString();
	}

	public static boolean isHome(String url) {
		boolean t = false;
		try {
			URL URL = new URL(url);
			if (URL.getHost().toLowerCase() == url.toLowerCase())
				t = true;
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
		return t;
	}

	public static String stripParas(String strUrl) {
		return strUrl.replaceAll("\\?.*", "").replaceAll("#.*", "");
	}

	/**
	 * 获取URL的pattern
	 * 
	 * @param strUrl
	 * @return
	 */
	public static String urlPattern(String strUrl) {
		String pattern = null;
		if (!getFile(strUrl).equals(strUrl) && strUrl.endsWith("/")) {
			strUrl = strUrl.substring(0, strUrl.lastIndexOf("/"));
			pattern = strUrl.substring(0, strUrl.indexOf(getFile(strUrl)));
			pattern = pattern.replaceAll("[0-9]", "");
		} else if (getFile(strUrl).equals(strUrl)) {
			pattern = strUrl;
		} else {
			pattern = strUrl.substring(0, strUrl.indexOf(getFile(strUrl)));
		}

		return pattern;
	}

	public static boolean patternMatches(String strUrl1, String strUrl2) {
		if (hashUrlFile(strUrl1)) {
			return patternMatchesByRegex(strUrl1, strUrl2);
		} else {
			String s1 = strUrl1.replaceAll("[0-9]", "");
			String s2 = strUrl2.replaceAll("[0-9]", "");
			return s1.equals(s2);
		}
	}

	/**
	 * 判断是否有如此形式的URL file：“a5a1VR8nSUBqgvid.html” <br>
	 * https://regex101.com/
	 * 
	 * @param strUrl
	 * @return
	 */
	public static boolean hashUrlFile(String strUrl) {
		String urlFile = getFile(strUrl);
		if (urlFile.matches("\\/\\W*([0-9]*[a-zA-Z]*)+?([0-9][a-zA-Z])+([0-9]*[a-zA-Z]*)+\\W?(s?html)?")) {
			return true;
		} else {
			return false;
		}
	}

	public static boolean patternMatchesByRegex(String s1, String s2) {
		return s2.matches(getRegex(s1));
	}

	public static String getRegex(String s) {
		String regexD = "[0-9]";
		String regexW = "[a-zA-Z]";
		String regexS = "\\S";
		StringBuilder sb = new StringBuilder();
		String last = "";
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			if (String.valueOf(c).matches(regexD)) {
				if (last.equals("")) {
					sb.append(regexD);
					last = regexD;
				} else if (last.equals(regexD)) {
					sb.append("+");
					last = regexD + "+";
				} else if (last.equals(regexD + "+")) {

				} else {
					sb.append(regexD);
					last = regexD;
				}
			} else if (String.valueOf(c).matches(regexW)) {
				if (last.equals("")) {
					sb.append(regexW);
					last = regexW;
				} else if (last.equals(regexW)) {
					sb.append("+");
					last = regexW + "+";
				} else if (last.equals(regexW + "+")) {

				} else {
					sb.append(regexW);
					last = regexW;
				}
			} else if (String.valueOf(c).matches(regexS)) {
				if (last.equals("")) {
					sb.append(regexS);
					last = regexS;
				} else if (last.equals(regexS)) {
					sb.append("+");
					last = regexS + "+";
				} else if (last.equals(regexS + "+")) {

				} else {
					sb.append(regexS);
					last = regexS;
				}
			}

		}
		return sb.toString();
	}

	/**
	 * 获取URL的文件，不包括目录路径 纯域名网址，其文件则为本身
	 * 
	 * @param strUrl
	 * @return
	 */
	public static String getFile(String strUrl) {
		URL url = null;
		String file = null;
		String uri = null;

		try {
			url = new URL(strUrl);
			if (url.getFile().equals("") || url.getFile().equals("/")) {
				file = strUrl;
			} else {
				uri = url.getFile();
				file = uri.substring(uri.lastIndexOf("/"));
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}

		return file;
	}
}
